package cn.elwy.rcp.ui.explorer.core.model;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yss.sofa.common.jdbc.DBType;
import com.yss.sofa.ide.builder.dbscript.Global;
import com.yss.sofa.ide.builder.dbscript.service.DBTypeMapService;
import com.yss.sofa.ide.builder.dbscript.util.XMLUtil;
import com.yss.sofa.ide.builder.dbscript.vo.ColumnType;
import com.yss.sofa.ide.builder.dbscript.vo.ColumnTypeMap;
import com.yss.sofa.ide.builder.dbscript.vo.DBTypeMap;
import com.yss.sofa.ide.builder.dbscript.vo.Limit;
import com.yss.sofa.ide.builder.dbscript.vo.TargetColumnType;

public class ScriptInfo {

  private final Logger logger = LoggerFactory.getLogger(ScriptInfo.class);

  private String projectName;
  private String sourceType;
  private String[] targetTypes = new String[] {};
  private DBInfo source;
  private DBInfo target;
  private List<String> createTableFiles = new ArrayList<String>();
  private List<String> insertDataFiles = new ArrayList<String>();
  private List<MappingRelationship> mrs = new ArrayList<MappingRelationship>();

  private String createFileName;
  private String insertFileName;
  private String dropFileName;

  public ScriptInfo() {
  }

  public String getCreateFileName() {
    return createFileName;
  }

  public void setCreateFileName(String createFileName) {
    this.createFileName = createFileName;
  }

  public String getInsertFileName() {
    return insertFileName;
  }

  public void setInsertFileName(String insertFileName) {
    this.insertFileName = insertFileName;
  }

  public String getDropFileName() {
    return dropFileName;
  }

  public void setDropFileName(String dropFileName) {
    this.dropFileName = dropFileName;
  }

  /**
   * @return the source
   */
  public DBInfo getSource() {

    return this.source;
  }

  /**
   * @param source the source to set
   */
  public void setSource(DBInfo source) {

    this.source = source;
  }

  /**
   * @return the target
   */
  public DBInfo getTarget() {

    return this.target;
  }

  /**
   * @param target the target to set
   */
  public void setTarget(DBInfo target) {

    this.target = target;
  }

  /**
   * @return the mrs
   */
  public List<MappingRelationship> getMrs() {

    return this.mrs;
  }

  /**
   * @param mrs the mrs to set
   */
  public void addMrs(MappingRelationship mr) {

    this.mrs.add(mr);
  }

  /**
   * @return the createTableFile
   */
  public List<String> getCreateTableFiles() {

    return this.createTableFiles;
  }

  /**
   * @param createTableFile the createTableFile to set
   */
  public void addCreateTableFiles(String createTableFile) {

    this.createTableFiles.add(createTableFile);
  }

  /**
   * @return the insertDataFile
   */
  public List<String> getInsertDataFiles() {

    return this.insertDataFiles;
  }

  /**
   * @param insertDataFile the insertDataFile to set
   */
  public void addInsertDataFiles(String insertDataFile) {

    this.insertDataFiles.add(insertDataFile);
  }

  public void getMappingRelationship() {
    DBTypeMapService dbTypeMapService = new DBTypeMapService();
    logger.debug("读取默认数据库类型配置");
    DBTypeMap dbTypeMap = dbTypeMapService.getDBTypeMap(Global.getMappingFile());
    ColumnTypeMap map = dbTypeMap.getColumnTypeMap(DBType.getEnumType(getSource().getDbType()),
        DBType.getEnumType(getTarget().getDbType()));
    if (map != null) {
      for (Map.Entry<ColumnType, TargetColumnType> entry : map.getColumnTypeMaps().entrySet()) {
        MappingRelationship mapping = new MappingRelationship();
        mapping.setSourceColType(entry.getKey());
        mapping.setTargetColType(covent(entry.getValue()));
        addMrs(mapping);
      }
    }
  }

  private com.yss.sofa.ide.builder.dbscript.model.TargetColumnType covent(TargetColumnType value) {
    com.yss.sofa.ide.builder.dbscript.model.TargetColumnType type = new com.yss.sofa.ide.builder.dbscript.model.TargetColumnType();
    type.setIsNullLength(value.isNullLength());
    type.setIsNullPrecision(value.isNullPrecision());
    type.setIsNullScale(value.isNullScale());
    type.setLength(value.getLength());
    type.setLengthText(value.getLengthText());
    type.setPrecision(value.getPrecision());
    type.setPrecisionText(value.getPrecisionText());
    type.setScale(value.getScale());
    type.setScaleText(value.getScaleText());
    type.setType(value.getType());
    return type;
  }

  private TargetColumnType covent1(com.yss.sofa.ide.builder.dbscript.model.TargetColumnType value) {
    TargetColumnType type = new TargetColumnType(value.getType(), value.getLengthText(), value.getPrecisionText(),
        value.getScaleText());
    type.setLength(value.getLength());
    type.setPrecision(value.getPrecision());
    type.setScale(value.getScale());
    return type;
  }

  public DBTypeMap getDBTypeMap() {
    DBTypeMap db = new DBTypeMap();
    db.setColumnTypeMap(DBType.getEnumType(getSource().getDbType()), DBType.getEnumType(getTarget().getDbType()),
        getColumnTypeMap());
    return db;
  }

  private ColumnTypeMap getColumnTypeMap() {
    ColumnTypeMap map = new ColumnTypeMap();
    for (MappingRelationship mr : this.mrs) {
      map.put(mr.getSourceColType(), covent1(mr.getTargetColType()));
    }
    return map;
  }

  /**
   * @return the projectName
   */
  public String getProjectName() {
    return this.projectName;
  }

  /**
   * @param projectName the projectName to set
   */
  public void setProjectName(String projectName) {
    this.projectName = projectName;
  }

  /**
   * @return the sourceType
   */
  public String getSourceType() {
    return this.sourceType;
  }

  /**
   * @param sourceType the sourceType to set
   */
  public void setSourceType(String sourceType) {
    this.sourceType = sourceType;
  }

  /**
   * @return the targetTypes
   */
  public String[] getTargetTypes() {
    return this.targetTypes;
  }

  /**
   * @param targetTypes the targetTypes to set
   */
  public void setTargetTypes(String[] targetTypes) {
    this.targetTypes = targetTypes;
  }

  public void addTargetTypes(String targetType) {
    String[] newStr = new String[targetType.length() + 1];
    System.arraycopy(this.targetTypes, 0, newStr, 0, this.targetTypes.length);
    newStr[newStr.length - 1] = targetType;
    this.targetTypes = newStr;
  }

  public static ScriptInfo loadScriptInfo(File file) {
    ScriptInfo info = null;
    try {
      String xmlText = XMLUtil.readFileByLines(file);
      // Logger.log(xmlText);
      info = XMLUtil.instance(ScriptInfo.class, xmlText);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return info;
  }

  public static ScriptInfo loadScriptInfo(IFile file) {
    return loadScriptInfo(file.getLocation().toFile());
  }

  public static void main(String args[]) {
    try {
      ScriptInfo si = new ScriptInfo();
      si.setProjectName("project");
      si.setSourceType("Oracle");
      si.setTargetTypes(new String[] { "DB2", "MSSQL" });
      DBInfo sinfo = new DBInfo();
      DBInfo tinfo = new DBInfo();
      MappingRelationship mapping = new MappingRelationship();
      ColumnType ct = new ColumnType();
      ct.setType("NUMBER");
      ct.setLengthLimit(new Limit("1..127"));
      com.yss.sofa.ide.builder.dbscript.model.TargetColumnType tt = new com.yss.sofa.ide.builder.dbscript.model.TargetColumnType(
          "NUMBER", "2", "", "");
      mapping.setSourceColType(ct);
      mapping.setTargetColType(tt);
      sinfo.setDbName("orcle");
      sinfo.setUserName("1");
      tinfo.setDbName("db2");
      si.setSource(sinfo);
      si.setTarget(tinfo);
      si.addCreateTableFiles("c:/aaa.xml");
      si.addCreateTableFiles("c:/ccc.xml");
      si.addInsertDataFiles("c:/bbb.xml");
      si.addMrs(mapping);
      String content = XMLUtil.createMXL(si);
      System.out.println(content);
      XMLUtil.createFile(content, "D:/aaabbbb.xml");
      ScriptInfo de = XMLUtil.instance(ScriptInfo.class, content);
      System.out.println(de.toString());
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
